import os
import time
import random
import threading
import atexit
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
from selenium.common.exceptions import TimeoutException, WebDriverException
from .logger import logger
from .config import config 
from .browser import browser_factory

class SingletonMeta(type):
    """单例元类，用于确保类只有一个实例。"""
    _instances = {}

    def __call__(cls, *args, **kwargs):
        if cls not in cls._instances:
            cls._instances[cls] = super().__call__(*args, **kwargs)
        return cls._instances[cls]


def switch_to_us(func):
    def wrapper(self, url: str, driver):
        location_text = WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.CSS_SELECTOR, '#glow-ingress-line2')))
        if location_text.text == 'Fontana 92337‌':
            return func(self, url, driver)
        logger.info('正在切换到美国')
        WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.ID, 'glow-ingress-block'))).click()
        input_box = WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.ID, 'GLUXZipUpdateInput')))
        input_box.send_keys(config.DEFAULT_ZIP_CODE)
        apply_btn = WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.CSS_SELECTOR, '#GLUXZipUpdate > span > input')))
        apply_btn.click()
        logger.info('apply按钮点击成功')
        time.sleep(1)
        driver.refresh()
        location_text = WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.CSS_SELECTOR, '#glow-ingress-line2')))
        if location_text.text == 'Fontana 92337‌':
            logger.info('切换到美国成功')
        return func(self, url, driver)
    return wrapper


def send_request(func):
    def wrapper(self, url: str, driver):
        logger.info(f"正在访问: {url}")
        # 添加页面加载超时设置（单位：秒）
        driver.set_page_load_timeout(config.LOAD_PAGE_TIMEOUT)
        driver.get(url)
            
        # 原有状态码检测逻辑保持不变
        status_code = driver.execute_script('return performance.getEntriesByType("navigation")[0].responseStatus')
        if status_code == 429:
            logger.error(f"请求 {url} 时遇到 429 状态码")
            raise Exception(f"请求 {url} 时遇到 429 状态码")
        WebDriverWait(driver, 30).until(lambda x: x.execute_script('return document.readyState') == 'complete')
        return func(self, url, driver)
    return wrapper


class CookieManager(metaclass=SingletonMeta):
    def __init__(self):
        self._request_lock = threading.Lock()
        self.running = True

    def init(self):
        self.driver = browser_factory.get_driver()
        self.cookies = {}
        self.lock = threading.Lock()
        self.update_event = threading.Event()
        self._start_cookie_updater()

    def _start_cookie_updater(self):
        """启动后台cookie更新线程"""
        self.gen_initial_cookie(config.BASE_URL, self.driver)
        def updater():
            while self.running:
                try:
                    interval = random.randint(120, 180)
                    timer = threading.Timer(interval, self.update_event.set)
                    timer.daemon = True
                    timer.start()
                    self.update_event.wait()
                    self.update_event.clear()
                    timer.cancel()
                    self._update_cookies()
                except Exception as e:
                    logger.error(f"Cookie更新线程异常: {str(e)}")

        threading.Thread(target=updater, daemon=True, name='cookie_updater').start()

    def shutdown(self):
        self.running = False
        self.update_event.set()  # 确保线程退出
        logger.info("CookieManager已关闭")

    def _update_cookies(self):
        try:
            with self.lock:
                self.driver.delete_all_cookies()
                self.driver.refresh()
                time.sleep(random.uniform(1, 3))
                self.cookies = {c['name']: c['value'] for c in self.driver.get_cookies()}
                logger.info("Cookie更新成功")
        except Exception as e:
            logger.info(f"Cookie更新异常: {str(e)}")

    def get_current_cookies(self):
        with self.lock:
            return self.cookies.copy()

    @send_request
    @switch_to_us
    def gen_initial_cookie(self, url: str):
        self.driver.get(url)
        self.cookies = {c['name']: c['value'] for c in self.driver.get_cookies()}


cookie_manager = CookieManager()